package mathive.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class SudokuCreator {

	private VerticalPanel mainPanel = new VerticalPanel();
	private ListBox diffBox = new ListBox();
	private Grid sudokuGrid = new Grid(9,9);
	private String difficulty;
	private String sudoku;
	private Button saveButton = new Button();
	private Button clearButton = new Button();
	private HTML title = new HTML("<h1 class='sudokuHeader'>Sudoku Creator</h1>");
	private SudokuServiceAsync sudokuSvc = GWT.create(SudokuService.class);
	private ListBox sudokuList = new ListBox();
	private Button deleteButton = new Button();

	public SudokuCreator(){

		saveButton.setText("Save Sudoku");
		clearButton.setText("Clear Sudoku");
		deleteButton.setText("Delete Sudoku");

		// Listen for mouse events on the cancel button.
		saveButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
//				mainPanel.clear();
				gridToString();
//				mainPanel.add(new HTML(sudoku));
//				System.out.println(sudoku);
				saveSudoku();
			}
		});

		// Listen for mouse events on the cancel button.
		clearButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				clearSudoku();
			}
		});

		// Listen for mouse events on the cancel button.
		deleteButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				deleteSudoku(Integer.parseInt(sudokuList.getItemText(sudokuList.getSelectedIndex()).substring(0, 1)));
			}
		});

	}

	private void initialize(){
		mainPanel.clear();

		sudokuGrid.setCellPadding(0);
		sudokuGrid.setCellSpacing(0);
		sudokuGrid.setStyleName("sudokuGrid");

		int numRows = sudokuGrid.getRowCount();
		int numColumns = sudokuGrid.getColumnCount();

		for (int row = 0; row < numRows; row++) {
			for (int col = 0; col < numColumns; col++) {
				TextBox textBox = new TextBox();
				textBox.ensureDebugId("cwBasicText-textbox");
				textBox.setStyleName("sudokuField");
				sudokuGrid.setWidget(row, col, textBox);
				sudokuGrid.getCellFormatter().setStyleName(row, col, "sudokuGridCell");

				//				sudokuGrid.getColumnFormatter().setStyleName(col, "sudokuGridCol");
			}
			//			sudokuGrid.getRowFormatter().setStyleName(row, "sudokuGridRow");
		}

		diffBox.addItem("Difficulty");
		diffBox.addItem("Easy");
		diffBox.addItem("Medium");
		diffBox.addItem("Hard");
		diffBox.setVisibleItemCount(1);

		mainPanel.add(title);
		mainPanel.add(diffBox);
		mainPanel.add(sudokuGrid);
		mainPanel.add(clearButton);
		mainPanel.add(saveButton);
		mainPanel.add(sudokuList);
		mainPanel.add(deleteButton);
		
		populateList();
	}

	public Widget getPanel(){
		initialize();
		return mainPanel;
	}

	private void saveSudoku(){
		
		if(diffBox.getItemText(diffBox.getSelectedIndex()).equals("Difficulty")){
			Window.alert("You have not selected a difficulty!");
			return;
		}
		
		int diff = 0;
		difficulty = diffBox.getItemText(diffBox.getSelectedIndex());
		if(difficulty.equals("Easy"))
			diff = ClientSudokuData.EASY;
		if(difficulty.equals("Medium"))
			diff = ClientSudokuData.MEDIUM;
		if(difficulty.equals("Hard"))
			diff = ClientSudokuData.HARD;
			
		
		// Initialize the service proxy.
		if (sudokuSvc == null) {
			sudokuSvc = GWT.create(SudokuService.class);
		}

		// Set up the callback object.
		AsyncCallback<String> callback = new AsyncCallback<String>() {
			public void onFailure(Throwable caught) {
				sudokuSaved("-1");				
			}

			public void onSuccess(String result) {
				sudokuSaved(result);
			}
		};

		System.out.println(diff+" "+" ["+sudoku+"] ");
		// Make the call to the fetch sudoku service.
		sudokuSvc.saveSudoku(diff, sudoku, callback);
	}


	private void clearSudoku(){
		int numRows = sudokuGrid.getRowCount();
		int numColumns = sudokuGrid.getColumnCount();

		for (int row = 0; row < numRows; row++) {
			for (int col = 0; col < numColumns; col++) {
				TextBox textBox = (TextBox)sudokuGrid.getWidget(row, col);
				textBox.setText("");
			}
		}
	}
	
	private void sudokuSaved(String id){
		mainPanel.clear();
		mainPanel.add(new HTML("Sudoku has been saved. It has ID " + id));
	}
	
	private void gridToString(){
		String sudokuString = "";
		
		int numRows = sudokuGrid.getRowCount();
		int numColumns = sudokuGrid.getColumnCount();

		for (int row = 0; row < numRows; row++) {
			for (int col = 0; col < numColumns; col++) {
				TextBox textBox = (TextBox)sudokuGrid.getWidget(row, col);
				if(!textBox.getText().matches("[1-9]"))
					sudokuString = sudokuString + " ";
				else
					sudokuString = sudokuString + textBox.getText();
			}
		}
		
		sudoku = sudokuString;
	}
	
	private void deleteSudoku(int id){
		// Initialize the service proxy.
		if (sudokuSvc == null) {
			sudokuSvc = GWT.create(SudokuService.class);
		}

		// Set up the callback object.
		AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() {
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
			}
			@Override
			public void onSuccess(Boolean result) {
				if (result){
					populateList();
				} else {
					Window.alert("The sudoku could not be deleted. Please contact systems administrator.");
				}
			}
		};

		// Make the call to the delete sudoku service.
		sudokuSvc.deleteSudoku(id, callback);
	}
	
	
	private void populateList(){
		sudokuList.clear();
		
		// Initialize the service proxy.
		if (sudokuSvc == null) {
			sudokuSvc = GWT.create(SudokuService.class);
		}

		// Set up the callback object.
		AsyncCallback<String[]> callback = new AsyncCallback<String[]>() {
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
			}
			@Override
			public void onSuccess(String[] result) {
				for(int i = 0; i < result.length; i++){
					sudokuList.addItem(result[i]);
				}
			}
		};

		// Make the call to the delete sudoku service.
		sudokuSvc.listSudokus(callback);
	}

}
